<?php

namespace App\Crontab;

use Hyperf\Crontab\Annotation\Crontab;
use Service\AppService\IdService;
use App\Service\AppService\RedisHashLock;
use App\Service\CommodityService\SupplierCommodityJdkeplerPullLogService;
use App\Service\CommodityService\SupplierCommodityPullLogService;
use Hyperf\Utils\WaitGroup;
use App\Service\Code\Normal;
use App\Model\CommodityModel\SupplierCompany;
use App\Model\CommodityModel\WarehouseInfo;
use Hyperf\DbConnection\Db;

/**
 * 京东开普勒供应商拉取商品
 * @Crontab(name="crontab_commodity_jdkepler_pull_goods", rule="*\/5 * * * * *", callback="execute", enable=false, memo="京东开普勒供应商拉取商品")
 */
class JdkeplerCrontab
{
    const TIME_WAIT = 60;//分钟
    const TIMEOUT_HOURS = 8;//接口卡起超时时间
    const PULL_FLAG = 'shopjdkepler';
    protected $redis_lock_key = 'crontab_commodity_jdkepler_pull_goods';
    protected $redis_key = 'pull_goods';

    /**
     * 开始执行业务脚本
     */
    public function execute()
    {
        try
        {
            //超过8个小时没拉完直接重新拉(这种一般是卡起了 一般拉完只要3-4个小时) 并且重置查询参数
            $this->getTimeoutSupplier();
            //供应商拉取标签
            $reult_query = SupplierCommodityPullLogService::instance()->getWaitPullSupplierWareHouseInfosByThirdPartyPlatformCode(self::PULL_FLAG);
            if( $reult_query['code'] != Normal::SUC ) {
                echo "{$this->redis_lock_key} is run pull goods is InVolid [no need pull goods supplier list]\r\n";
                return false;
            }
            $supplierList = $reult_query['data'];
            //所有供应商拉取完成间隔时间
            $SupplierPullWaitTime = self::TIME_WAIT;

            //预计下次拉取商品时间
            $nextPeriod = date("Y-m-d H:i:s", time() + $SupplierPullWaitTime * 60);
            //开始协助并发拉取
            // $count = count($supplierList);
            // $wg = new WaitGroup();
            // $wg->add($count);
            foreach ($supplierList as $supplier)
            {
                // co(function () use ($supplier,$nextPeriod,$wg)
                // {
                //     $this->querySingleSupplierGoods($supplier,$nextPeriod);

                    // SupplierID
                    $redis_lock_key = $this->redis_lock_key . '_' . $supplier['SupplierID'];
                    $kVal   = IdService::instance()->getOtherID();
                    $isLock = RedisHashLock::instance()->getLockHash($this->redis_key,$redis_lock_key,$kVal);
                    if( $this->isEnable() && $isLock )
                    {
                        Waiter(function() use ($supplier, $nextPeriod)
                        {
                            // SupplierCommodityJdkeplerPullLogService::instance()->runTask();
                            SupplierCommodityJdkeplerPullLogService::instance()->querySingleSupplierGoods($supplier, $nextPeriod);
                        },86400);
                        RedisHashLock::instance()->unLockHash($this->redis_key,$redis_lock_key,$kVal);
                    }
                    else
                    {
                        echo "{$redis_lock_key} is run pull goods is InVolid \r\n";
                    }
                    // $wg->done();
                // });
            }
            // $wg->wait();
            // return Normal::returnCode(Normal::SUC, '拉取完成');




            // $kVal   = IdService::instance()->getOtherID();
            // $isLock = RedisHashLock::instance()->getLockHash($this->redis_key,$this->redis_lock_key,$kVal);
            // if( $this->isEnable() && $isLock )
            // {
            //     Waiter(function()
            //     {
            //         SupplierCommodityJdkeplerPullLogService::instance()->runTask();
            //     },86400);
            //     RedisHashLock::instance()->unLockHash($this->redis_key,$this->redis_lock_key,$kVal);
            // }
            // else
            // {
            //     echo "{$this->redis_lock_key} is run pull goods is InVolid \r\n";
            // }
        } catch ( \Throwable $th ) {
            echo "{$this->redis_lock_key} is pull goods is error now ，{$th->getMessage()},{$th->getFile()},{$th->getLine()} \r\n";
            RedisHashLock::instance()->unLockHash($this->redis_key,$this->redis_lock_key,$kVal);
        }
    }

    /**
     * 是否开启可用
     */
    public function isEnable(): bool
    {
        return env("is_enable_{$this->redis_lock_key}",false);
    }

    /**
     * 查询超过8个小时没拉完的供应商 并且重置查询参数
     */
    protected function getTimeoutSupplier(){
        $table = WarehouseInfo::instance()->getTable();
        $wareHouseParam = WarehouseInfo::instance()
        ->from($table." as w")
        ->select([
            Db::raw("CONCAT(w.SupplierID,'') as SupplierID"),
            's.SupplierCode',
            's.SupplierName',
            's.OrderDockMode',
            's.IsTryUpdateCommodityArchives',
            's.ThirdPartyPlatformCode',
            's.SyncMode',
            Db::raw("CONCAT(w.ID,'') as WarehouseID"),
            'w.WarehouseName',
            'w.JsonBody',
            'w.CanModifyStock',
        ])
        ->join('suppliercompany_s2b as s',"s.ID","=","w.SupplierID")
        ->where('s.ThirdPartyPlatformCode',self::PULL_FLAG)
        ->where('s.CommodityGetTaskStatus',1)
        ->where('s.CompanyStatus',1)//供应商启用状态
        ->where('s.OrderDockMode',0)//供应商接口仓
        ->where('s.CommodityGetMode',3)//供应商商品接口主动拉取模式
        ->where('w.WarehouseType',1)//接口模式
        ->where('w.ExamineState',1)
        ->whereRaw("DATE_ADD(s.CommodityGetNetPeriod, INTERVAL " . self::TIMEOUT_HOURS . " HOUR) <= NOW()")
        ->get()
        ->toArray();
        if( empty($wareHouseParam) ) {
            return Normal::returnCode(Normal::FAIL,"未找到满足条件的供应商数据");
        }
        $supplierIds = array_column($wareHouseParam, 'SupplierID');
        //超过8个小时没拉完直接重新拉(这种一般是卡起了 一般拉完只要3-4个小时)
        $upData = [
            'CommodityGetTaskStatus' => 0,
            'CommodityGetFinishCount' => 0,
            'CommodityGetFinishUseTime' => 0,
            'CommodityGetNetPeriod'     => date("Y-m-d H:i:s", time() - self::TIME_WAIT * 60)
        ];
        SupplierCompany::whereIn('ID', $supplierIds)->update($upData);
        //删除redis锁缓存
        foreach ($supplierIds as $supplierId) {
            $redis_lock_key = $this->redis_lock_key . '_' . $supplierId;
            RedisHashLock::instance()->unLockHash($this->redis_key,$redis_lock_key);
        }
        return Normal::returnCode(Normal::SUC,"操作成功",$wareHouseParam);
    }
}